/*
 * @Author: 0x9DEFA478
 * @Date: 2024-07-28 21:50:57
 * @LastEditTime: 2024-09-16 18:17:58
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "./H_TS_LL_Core.h"
#include "./H_TS_LL.h"




H_TS_LL_Core H_TS_LL_Core_Instance;




static int TickProcess(H_TS_Tick tick){
  H_TS_Thread* p;
  H_TS_Tick t_tick;
  H_TS_Tick last_tick;
  int isScheduler;
  
  isScheduler=0;

  //睡眠线程判定
  p=H_TS_LL_Core_Instance.SleepThreads;
  if(p!=NULL){
    last_tick=tick;

    t_tick=p->BlockObject.Sleep.Tick;
    if(t_tick<=last_tick){
      isScheduler=-1;
      H_TS_LL_Core_Instance.SleepThreadsEvent=-1;
    }

    for(;;){
      if(t_tick>last_tick){
        p->BlockObject.Sleep.Tick=t_tick-last_tick;
        last_tick=0;
        break;
      }else{
        p->BlockObject.Sleep.Tick=0;
        p->Status=vH_TS_Thread_Status_Ready;
        last_tick-=t_tick;

        p=p->List.Sleep.Next;
        if(p==NULL){
          break;
        }
        t_tick=p->BlockObject.Sleep.Tick;
      }
    }
  }

  //时间限制阻塞判定
  p=H_TS_LL_Core_Instance.TimeBlockThreads;
  if(p!=NULL){
    last_tick=tick;

    t_tick=p->BlockObject.TimeBlock.SleepTick;
    if(t_tick<=last_tick){
      isScheduler=-1;
    }

    for(;;){
      if(t_tick>last_tick){
        p->BlockObject.TimeBlock.SleepTick=t_tick-last_tick;
        last_tick=0;
        break;
      }else{
        p->BlockObject.TimeBlock.SleepTick=0;
        p->Status=vH_TS_Thread_Status_Ready;//线程就绪
        ((H_TS_Thread* volatile *)p->BlockObject.TimeBlock.BlockObject)[0]=NULL;//清除占用标记
        H_TS_LL_AddThreadToTimeBlock_IRQUnblockThreads(p);

        p=p->List.TimeBlock.Next;
        if(p==NULL){
          break;
        }
        t_tick=p->BlockObject.TimeBlock.SleepTick;
      }
    }
  }

  return isScheduler;
}




//Tick中断回调
void H_TS_LL_TickCallback(void* v){

  H_TS_LL_Core_Instance.RunningTick++;

  if((H_TS_LL_Core_Instance.SchedulerSuspend!=0)||(H_TS_LL_Core_Instance.SysTickSuspend!=0)){
    //由线程申请的调度挂起
#if vH_TS_IsEnableSimpleTick==0
    H_TS_LL_Core_Instance.MissTickCount++;
    oH_TS_LL_ISR_CallScheduleISR();
#endif
    return;
  }

  if(0!=TickProcess(1)){
    oH_TS_LL_CallScheduleISR();
  }

}

//线程调度 
void* H_TS_LL_CurrentThreadRefresh(){
  H_TS_Thread* p;
  H_TS_Thread* p_last;
  H_TS_Thread* p_next;
  Hsize SleepThreadsEvent;
#if vH_TS_IsEnableSimpleTick==0
  H_TS_Tick MissTickCount;
#endif
  
  H_TS_Thread* p_temp;
  Hsize Priority;
  int retVal;


  if(H_TS_LL_Core_Instance.SchedulerSuspend!=0){
    return cH_TS_LL_ThisThread(H_TS_LL_Core_Instance);//调度已挂起
  }
  oH_TS_LL_ResumeSchedulerDone();


#if vH_TS_IsEnableSimpleTick
  oH_TS_LL_TickSuspend();//挂起Tick响应
#else
  MissTickCount=H_TS_LL_Core_Instance.MissTickCount;
  if(MissTickCount>0){
    H_TS_LL_Core_Instance.MissTickCount=0;
  
    oH_TS_LL_TickSuspend();//挂起Tick响应

    TickProcess(MissTickCount);
  }else{
    oH_TS_LL_TickSuspend();//挂起Tick响应
  }
#endif
  SleepThreadsEvent=H_TS_LL_Core_Instance.SleepThreadsEvent;
  //睡眠线程处理
  if(SleepThreadsEvent!=0){
    H_TS_LL_Core_Instance.SleepThreadsEvent=0;

    p=H_TS_LL_Core_Instance.SleepThreads;
    while(p!=NULL){
      if(p->Status==vH_TS_Thread_Status_Ready){

        p_next=p->List.Sleep.Next;

        //从睡眠线程链表中移除(第一个节点)
        if(p_next!=NULL){
          p_next->List.Sleep.Last=NULL;
        }

        //添加到就绪链表
        H_TS_LL_ThreadAddToReadyList(p,p_temp,Priority,retVal);

      }else{
        //对于睡眠链表, 就绪线程不会分散排列
        break;
      }

      p=p_next;
    }
    H_TS_LL_Core_Instance.SleepThreads=p;
    
  }

  //时间限制阻塞处理
  while(NULL!=(p=H_TS_LL_AtomicAccess_ListPop((void* volatile*)&H_TS_LL_Core_Instance.TimeBlock_IRQUnblockThreads,cH_TS_LL_OffsetOfStructMember(H_TS_Thread,IRQUnblockList.Next)))){
    H_TS_LL_AtomicAccess_SetValue(&p->IsIRQUnblock,0);

    if(p->IsNotReady!=0){
      //从时间限制线程链表中移除
      p_next=p->List.TimeBlock.Next;
      p_last=p->List.TimeBlock.Last;
      if(p_last==NULL){
        H_TS_LL_Core_Instance.TimeBlockThreads=p_next;
      }else{
        p_last->List.TimeBlock.Next=p_next;
      }
      if(p_next!=NULL){
        p_next->BlockObject.TimeBlock.SleepTick+=p->BlockObject.TimeBlock.SleepTick;
        p_next->List.TimeBlock.Last=p_last;
      }

      //添加到就绪链表
      H_TS_LL_ThreadAddToReadyList(p,p_temp,Priority,retVal);
    }
  }
  oH_TS_LL_ReusmeTick();//恢复Tick响应
  

  //阻塞线程处理
  while(NULL!=(p=H_TS_LL_AtomicAccess_ListPop((void* volatile*)&H_TS_LL_Core_Instance.Block_IRQUnblockThreads,cH_TS_LL_OffsetOfStructMember(H_TS_Thread,IRQUnblockList.Next)))){
    H_TS_LL_AtomicAccess_SetValue(&p->IsIRQUnblock,0);

    if(p->IsNotReady!=0){
      //从阻塞线程链表中移除
      p_next=p->List.Block.Next;
      p_last=p->List.Block.Last;
      if(p_last==NULL){
        H_TS_LL_Core_Instance.BlockThreads=p_next;
      }else{
        p_last->List.Block.Next=p_next;
      }
      if(p_next!=NULL){//p_next不一定存在
        p_next->List.Block.Last=p_last;
      }

      //添加到就绪链表
      H_TS_LL_ThreadAddToReadyList(p,p_temp,Priority,retVal);
    }
  }



  (void)retVal;


  p_last=cH_TS_LL_ThisThread(H_TS_LL_Core_Instance);
  p_next=H_TS_LL_Core_Instance.ReadyThreads;
  if(p_last!=p_next){
    
#if vH_TS_IsEnableCPULoadCalculate != 0
    H_TS_DeltaTime DT;
    H_TS_RunTime CPU_Load_RunningTime;

    CPU_Load_RunningTime=H_TS_LL_Core_Instance.CPU_Load_RunningTime;
    if(CPU_Load_RunningTime<vH_TS_CPULoad_T){
      H_TS_LL_GetDT(DT);
      H_TS_LL_Core_Instance.CPU_Load_RunningTime=CPU_Load_RunningTime+DT;
      p_last->CPU_Load_RunningTime+=DT;
    }
#endif

    //下次运行的线程更新
    cH_TS_LL_ThisThread(H_TS_LL_Core_Instance)=p_next;

    p=H_TS_LL_Core_Instance.IdleThread;
    if(p_next==p){
      H_TS_LL_Core_Instance.IdleThreadResume=-1;//提示空闲线程 从其他线程转到空闲线程
    }

#ifdef H_TS_ErrnoUpdate
    H_TS_ErrnoUpdate(&p_last->Errno,&p_next->Errno);
#endif
  }
  
  return p_next;
}




void H_TS_LL_ThreadListForceAddToReadyList(H_TS_Thread* Thread){
  H_TS_Thread* Thread_Next;
  H_TS_Thread* p_next;
  H_TS_Thread* p_last;
  H_TS_Thread* ReadyThreads;
  Hsize Priority;

  ReadyThreads=H_TS_LL_Core_Instance.ReadyThreads;

  while(Thread!=NULL){
    Thread->List.Ready.IsSubReady=0;
    Thread_Next=Thread->List.Ready.Next;

    p_next=ReadyThreads;

    oH_TS_Assert_Core(p_next==NULL,"H_TS:H_TS_LL_ThreadListForceAddToReadyList():不可能出现无就绪线程的情况(至少存在一个空闲线程)");

    Priority=Thread->Priority;
    if(p_next->Priority<Priority){
      //优先级不是当前就绪最高的

      p_next=p_next->List.Ready.Next;
      while(p_next!=NULL){

        if(p_next->Priority>=Priority){
          //找到插入点

          p_last=p_next->List.Ready.Last;

          Thread->List.Ready.Next=p_next;
          Thread->List.Ready.Last=p_last;
          p_last->List.Ready.Next=Thread;
          p_next->List.Ready.Last=Thread;

          goto lContinue;
        }

        p_next=p_next->List.Ready.Next;
      }
      //无插入点 添加到尾部

      oH_TS_Crash("H_TS:H_TS_LL_ThreadListForceAddToReadyList():由于空闲线程的存在 不可能无插入点\r\n");
      for(;;){
      }
    }else{
      //高优先级 直接添加到头部

      Thread->List.Ready.Last=NULL;
      Thread->List.Ready.Next=p_next;
      p_next->List.Ready.Last=Thread;
      ReadyThreads=Thread;
    }

lContinue:
    Thread=Thread_Next;
  }

  H_TS_LL_Core_Instance.ReadyThreads=ReadyThreads;

}

void H_TS_LL_ThreadAddToSleepList(H_TS_Thread* Thread,H_TS_Tick NumOfTick){
  H_TS_Thread* p_last;
  H_TS_Thread* p_next;
  H_TS_Tick t_tick;

  p_last=H_TS_LL_Core_Instance.SleepThreads;
  if(p_last==NULL){
    //链表空 直接添加
    Thread->BlockObject.Sleep.Tick=NumOfTick;
    Thread->List.Sleep.Next=NULL;
    Thread->List.Sleep.Last=NULL;
    H_TS_LL_Core_Instance.SleepThreads=Thread;
  }else{
    //链表不为空 按解除阻塞顺序插入

    p_next=H_TS_LL_Core_Instance.SleepThreads;
    p_last=NULL;

    while(p_next!=NULL){

      t_tick=p_next->BlockObject.Sleep.Tick;

      if(t_tick>NumOfTick){
        //找到插入点

        Thread->BlockObject.Sleep.Tick=NumOfTick;
        p_next->BlockObject.Sleep.Tick=t_tick-NumOfTick;

        //插入节点
        Thread->List.Sleep.Last=p_last;
        Thread->List.Sleep.Next=p_next;
        p_next->List.Sleep.Last=Thread;
        if(p_last==NULL){
          H_TS_LL_Core_Instance.SleepThreads=Thread;
        }else{
          p_last->List.Sleep.Next=Thread;
        }

        return;
      }else{
        NumOfTick-=t_tick;
      }
      
      p_last=p_next;
      p_next=p_last->List.Sleep.Next;
    }

    Thread->BlockObject.Sleep.Tick=NumOfTick;

    //仍未找到插入点,插入到最后
    //此时p_last不可能为NULL
    Thread->List.Sleep.Last=p_last;
    Thread->List.Sleep.Next=NULL;
    p_last->List.Sleep.Next=Thread;
  }
}

void H_TS_LL_ThreadAddToTimeBlockList(H_TS_Thread* Thread,H_TS_Tick Timeout){
  H_TS_Thread* p_last;
  H_TS_Thread* p_next;
  H_TS_Tick t_tick;

  p_last=H_TS_LL_Core_Instance.TimeBlockThreads;
  if(p_last==NULL){
    //链表空 直接添加
    Thread->BlockObject.TimeBlock.SleepTick=Timeout;
    Thread->List.TimeBlock.Next=NULL;
    Thread->List.TimeBlock.Last=NULL;
    H_TS_LL_Core_Instance.TimeBlockThreads=Thread;
  }else{
    //链表不为空 按解除阻塞顺序插入

    p_next=H_TS_LL_Core_Instance.TimeBlockThreads;
    p_last=NULL;

    while(p_next!=NULL){

      t_tick=p_next->BlockObject.TimeBlock.SleepTick;

      if(t_tick>Timeout){
        //找到插入点

        Thread->BlockObject.TimeBlock.SleepTick=Timeout;
        p_next->BlockObject.TimeBlock.SleepTick=t_tick-Timeout;

        //插入节点
        Thread->List.TimeBlock.Last=p_last;
        Thread->List.TimeBlock.Next=p_next;
        p_next->List.TimeBlock.Last=Thread;
        if(p_last==NULL){
          H_TS_LL_Core_Instance.TimeBlockThreads=Thread;
        }else{
          p_last->List.TimeBlock.Next=Thread;
        }

        return;
      }else{
        Timeout-=t_tick;
      }
      
      p_last=p_next;
      p_next=p_last->List.TimeBlock.Next;
    }

    Thread->BlockObject.TimeBlock.SleepTick=Timeout;

    //仍未找到插入点,插入到最后
    //此时p_last不可能为NULL
    Thread->List.TimeBlock.Last=p_last;
    Thread->List.TimeBlock.Next=NULL;
    p_last->List.TimeBlock.Next=Thread;
  }
}



